#include "httprequest.h"

HttpRequest::HttpRequest()
{
    Init();
}

void HttpRequest::Init()
{
    path_ = version_ = body_ = "";
    state_ = ParseState::PARSE_LINE;
    header_.clear();
    post_.clear();
}

bool HttpRequest::Parse(Buffer &buffer)
{
    static const char CRLF[] = "\r\n";
    if (buffer.ReadableBytes() <= 0)
    {
        return false;
    }
    while (buffer.ReadableBytes() > 0 && state_ != ParseState::FINISH)
    {
        // 设置当前解析的请求行
        const char *lineEnd = std::search(buffer.BeginRead(), buffer.BeginWrite(), CRLF, CRLF + 2);
        std::string line(buffer.BeginReadConst(), lineEnd);
        // 状态机
        switch (state_)
        {
        case ParseState::PARSE_LINE:
        {
            if(!ParseRequestLine(line)) {
                return false;
            }
            ParsePath();
            state_ = ParseState::PARSE_HEAD;
            break;
        }
        case ParseState::PARSE_HEAD:
        {
            ParseHeader(line);
            if(buffer.ReadableBytes() <= 2) {
                state_ = ParseState::FINISH;
            }
            break;
        }
        case ParseState::PARSE_BODY:
        {
            ParseBody(line);
            break;
        }
        default:
            break;
        }
        if(lineEnd == buffer.BeginWrite()) break;
        buffer.RetrieveUntil(lineEnd+2);
    }
    LOG(INFO) << method_ << " | " << path_ << " | " << version_;
    return true;
}

std::string HttpRequest::GetMethod()
{
    return method_;
}

std::string HttpRequest::GetPath() const
{
    return path_;
}

std::string &HttpRequest::GetPath()
{
    return path_;
}

std::string HttpRequest::GetVersion() const
{
    return version_;
}

std::string HttpRequest::GetPost(const std::string &key) const
{
    assert(key != "");
    if (post_.count(key) == 1)
    {
        return post_.find(key)->second;
    }
    return "";
}

std::string HttpRequest::GetPost(const char *key) const
{
    assert(key != "");
    if (post_.count(key) == 1)
    {
        return post_.find(key)->second;
    }
    return "";
}

bool HttpRequest::IsKeepAlive() const
{
    if (header_.count("Connection") == 1)
    {
        return header_.find("Connection")->second == "keep-alive" && version_ == "1.1";
    }
    return false;
}

bool HttpRequest::ParseRequestLine(const std::string& line)
{
    std::regex patten("^([^ ]*) ([^ ]*) (HTTP/[^ ]*)$");
    std::smatch subMatch;
    if(std::regex_match(line, subMatch, patten)) {
        method_ = subMatch[1];
        path_ = subMatch[2];
        version_ = subMatch[3];
        return true;
    }
    return false;
}

void HttpRequest::ParseHeader(const std::string& line)
{
    std::regex patten("^([^:]*): ?(.*)$");
    std::smatch subMatch;
    if(std::regex_match(line, subMatch, patten)) {
        header_[subMatch[1]] = subMatch[2];
    } else {
        state_ = ParseState::PARSE_BODY;
    }
    return;
}

void HttpRequest::ParseBody(const std::string& line)
{
    body_ = line;
    ParsePost();
    state_ = ParseState::FINISH;
    LOG(INFO) << "body:" << body_ << "\nlen:" << line.size();
}

void HttpRequest::ParsePath()
{
    if(path_ == "/"){
        path_ = "/index.html";
    }// TODO 完善更多的资源
}

//TODO 解析post请求
void HttpRequest::ParsePost()
{
}
